home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
IRIS Performer 2.2 Friends Demo
/
SGI IRIS Performer 2.2 Friends Demo.iso
/
friends
/
medit
/
pfLoader
/
Internalstuff
/
convert.c
next >
Wrap
Text File
|
1997-11-20
|
6KB
|
222 lines
/************************************************************************
Check for Null-matrices
************************************************************************/
void CheckMatrixForNull(pfMatrix mat) {
int i, j;
for (i=0; i<4; i++) {
for (j=0; j<4; j++) {
if (mat[i][j] ISNT 0.0) {
return;
}
}
}
pfMakeIdentMat(mat);
}
/************************************************************************
Maintain a list of the objects we have already converted
************************************************************************/
void AddToObjectList(Vars v, mwObjectPtr o, pfNode *data)
{
if (v->NoObjects IS v->MaxObjects) {
v->MaxObjects += 100;
if (v->NoObjects IS 0) {
v->ObjectList = Allocate(v->MaxObjects*sizeof(ObjList));
}
else {
v->ObjectList = Reallocate(v->ObjectList, v->MaxObjects*sizeof(ObjList));
}
}
v->ObjectList[v->NoObjects].obj = o;
v->ObjectList[v->NoObjects].data = data;
v->NoObjects++;
}
static pfNode *FindObject(Vars v, mwObjectPtr o)
{
reg int i;
for (i=0; i<v->NoObjects; i++) {
if (v->ObjectList[i].obj IS o) {
return v->ObjectList[i].data;
}
}
return NULL;
}
/************************************************************************
Convert the file
************************************************************************/
static void DoConvert(mwTreePtr tree, pfNode *parent, Vars v)
{
reg int count;
reg float distance;
reg mwTreePtr next, a;
reg pfDCS *dcs;
reg pfSCS *scs;
reg pfLOD *lod;
pfMatrix mat, inv;
reg pfGroup *group;
reg pfSwitch *Switch;
reg pfSequence *Sequence;
reg pfNode *obj, *newnode, *newparent, *namenode;
while (tree) {
newnode = newparent = namenode = NULL;
next = tree->Down;
switch (tree->Type) {
case mwGroupBranch: group = pfNewGroup();
newnode = (pfNode*)group;
tree->Converted = group;
break;
case mwPolygonBranch: newnode = ConvertPolygonBranch(tree);
tree->Converted = newnode;
break;
case mwLodBranch: lod = pfNewLOD();
pfAddChild(parent, lod);
pfNodeName(lod, "Lod");
count = 0;
distance = 0.0;
while (tree) {
group = pfNewGroup();
tree->Converted = group;
pfAddChild(lod, group);
pfNodeName(group, tree->Name);
pfLODRange(lod, count++, distance);
DoConvert(tree->Across, (pfNode*)group, v);
distance = tree->SwitchOut;
tree = tree->Down;
}
pfLODRange(lod, count, distance);
next = NULL;
newnode = NULL;
break;
case mwInstanceBranch: ConvertMatrix(tree->Transformation, mat);
scs = pfNewSCS(mat);
newnode = (pfNode*)scs;
if (obj = FindObject(v, tree->Obj)) {
pfAddChild(newnode, pfClone(obj, 0));
}
else {
DoConvert(tree->Obj->Tree, newnode, v);
if (pfGetNumChildren(newnode) > 0) {
AddToObjectList(v, tree->Obj, pfGetChild(newnode, 0));
}
}
namenode = pfGetChild(scs, 0);
tree->Converted = namenode;
AddEngines(namenode, tree->Obj, FALSE);
break;
case mwSwitchBranch: switch (tree->SubType) {
case mwSwitchSequence: Sequence = pfNewSeq();
newnode = (pfNode*)Sequence;
count = 0;
a = tree->Across;
while (a) {
count++;
a = a->Down;
}
if (count > 0) {
if (tree->SeqTime IS 0.0) {
pfSeqTime(Sequence, PFSEQ_ALL, 1.0/60.0);
}
else {
pfSeqTime(Sequence, PFSEQ_ALL, tree->SeqTime/count);
}
pfSeqInterval(Sequence, PFSEQ_CYCLE, 0, PFSEQ_ALL);
pfSeqDuration(Sequence, 1.0, PFSEQ_ALL);
pfSeqMode(Sequence, PFSEQ_START); }
else {
NOTIFY"Warning: Sequence %s has no children)\n", tree->Name);
}
tree->Converted = Sequence;
break;
default: Switch = pfNewSwitch();
newnode = (pfNode*)Switch;
tree->Converted = Switch;
break;
}
break;
case mwDcsBranch: dcs = pfNewDCS();
newnode = (pfNode*)dcs;
/* Generate SCS -> DCS -> SCS */
ConvertMatrix(tree->DcsMatrix, mat);
CheckMatrixForNull(mat);
pfInvertFullMat(inv, mat);
scs = pfNewSCS(mat); pfNodeName(scs, "there");
pfAddChild(parent, scs);
pfAddChild(scs, dcs);
scs = pfNewSCS(inv); pfNodeName(scs, "back");
newparent = (pfNode*)dcs;
newnode = (pfNode*)scs;
namenode = (pfNode*)dcs;
tree->Converted = dcs;
break;
default: group = pfNewGroup();
newnode = (pfNode*)group;
tree->Converted = group;
break;
}
if (newnode) {
pfAddChild(((newparent)? newparent: parent), newnode);
if (tree->Name) {
pfNodeName(((namenode)? namenode: newnode), tree->Name);
}
if (tree->Across) {
DoConvert(tree->Across, newnode, v);
}
}
tree = next;
}
}
/************************************************************************
Convert a model file to Performer Geometry
************************************************************************/
pfNode *pfdConvertFrom_mw(mwFilePtr f)
{
Vars v;
pfNode *root;
mwObjectPtr o;
o = f->FirstObject;
if (o) {
while (o) { /* Decide what to convert */
if (o->IsTopLevel) {
break;
}
o = o->Next;
}
if (!o) {
o = f->FirstObject;
}
root = (pfNode*)pfNewGroup(); /* Create a root branch for the file */
pfNodeName(root, o->Name);
v = NewConvertVars(); /* Convert it */
arena = pfGetSharedArena();
DoConvert(o->Tree, root, v);
AddEngines(root, o, TRUE);
FreeConvertVars(v);
CleanDatabase(root);
return root;
}
else {
NOTIFY"Nothing in model file!\n");
return NULL;
}
}